# 由于没有提供EmNormalPositionParser的Java代码，这里假设它的功能和EmCreditPositionParser类似
# 以下是一个简单的示例，可根据实际情况修改
import csv
import re
from decimal import Decimal
from typing import List
from datetime import datetime

class EmNormalStockPosition:
    def __init__(self):
        # 序号
        self.sequence = 0
        # 证券代码
        self.stock_code = ""
        # 证券名称
        self.stock_name = ""
        # 持仓数量
        self.position_quantity = 0
        # 可用数量
        self.available_quantity = 0
        # 成本价
        self.cost_price = Decimal(0)
        # 最新价
        self.latest_price = Decimal(0)
        # 持仓盈亏比例
        self.position_profit_loss_ratio = ""
        # 持仓盈亏
        self.position_profit_loss = Decimal(0)
        # 当日盈亏比例
        self.daily_profit_loss_ratio = ""
        # 当日盈亏
        self.daily_profit_loss = Decimal(0)
        # 个股仓位
        self.stock_position_ratio = ""
        # 最新市值
        self.market_value = Decimal(0)
    def __repr__(self):
        return (f"EmNormalStockPosition(代码:{self.stock_code}, 名称:{self.stock_name}, "
                f"数量:{self.position_quantity}, 市价:{self.latest_price})")

class EmNormalPosition:
    #导出时间 总资产 可用资金 可取资金 证券市值
    def __init__(self):
        # 导出时间
        self.export_time = datetime
        # 总资产
        self.total_assets = Decimal(0)
        # 可用资金
        self.available_funds = Decimal(0)
        # 可取资金
        self.withdrawable_funds = Decimal(0)
        # 证券市值
        self.market_value = Decimal(0)
        # 持仓项列表
        self.positions: List[EmNormalStockPosition] = []
    def __repr__(self):
        return (f"EmNormalPosition(时间:{self.export_time}, 总资产:{self.total_assets}, "
                f"持仓数:{len(self.positions)})")

class EmNormalPositionParser:
    def __init__(self):
        self.headers = {}  # 存储表头映射
        pass

    def parse(self, file_path: str) -> EmNormalPosition:
        """
        解析东方财富普通账户持仓CSV文件
        :param file_path: CSV文件路径
        :return: 持仓数据对象
        """
        position_data = EmNormalPosition()
        position_items = []

        try:
            with open(file_path, 'r', encoding='GBK') as file:
                lines = [line.strip() for line in file if line.strip()]  # 读取非空行

                if len(lines) < 3:
                    raise ValueError("CSV文件格式错误：至少需要3行数据（表头+概要+持仓）")

                # 解析账户总体信息（从第二行开始找实际数据）
                summary_found = False
                header_found = False

                for i, line in enumerate(lines):
                    if line.startswith('20'):  # 识别日期行
                        row = re.split(r'\s{2,}', line)  # 按2个及以上空格分割
                        self.parse_account_info(position_data, row)
                        summary_found = True
                        stock_lines = lines[i + 1:]  # 后续为持仓数据
                        break

                if not summary_found:
                    raise ValueError("未找到有效的账户概要信息行")

                # 查找表头行（第三行）
                for i, line in enumerate(stock_lines):
                    if '序' in line and '证券代码' in line and '证券名称' in line:
                        # 找到表头行
                        header_row = re.split(r'\s{2,}', line)
                        self.parse_headers(header_row)
                        header_found = True
                        stock_lines = stock_lines[i + 1:]  # 后续为持仓数据
                        break

                if not header_found:
                    raise ValueError("未找到有效的表头行")

                # 解析持仓明细
                for line in stock_lines:
                    if line[0].isdigit():  # 验证序号列
                        row = re.split(r'\s{2,}', line)
                        if len(row) >= len(self.headers):
                            position_items.append(self.parse_position_item_by_headers(row))

            position_data.positions = position_items
        except Exception as e:
            print(f"文件读取异常: {e}")
            raise

        return position_data

    def parse_account_info(self, position_data: EmNormalPosition, summary_row: List[str]):
        """
        解析账户总体信息
        :param position_data: 持仓数据对象
        :param summary_row: 账户总体信息行
        """
        if len(summary_row) >= 5:
            # 这里假设前8列是账户总体信息，可根据实际情况修改
            # 导出时间 总资产 可用资金 可取资金 证券市值
            position_data.export_time = datetime.strptime(summary_row[0], "%Y/%m/%d %H:%M")  # "2025/06/08 11:34"
            position_data.total_assets = self.parse_decimal(summary_row[1])
            position_data.available_funds = self.parse_decimal(summary_row[2])
            position_data.withdrawable_funds = self.parse_decimal(summary_row[3])
            position_data.market_value = self.parse_decimal(summary_row[4])

    def parse_headers(self, header_row: List[str]):
        """解析表头，建立列名到索引的映射"""
        self.headers = {}
        for i, header in enumerate(header_row):
            header = header.strip()
            if header:  # 忽略空表头
                self.headers[header] = i
        print(f"解析到的表头映射: {self.headers}")

    def get_column_value(self, row: List[str], column_name: str, default=""):
        """根据列名获取值"""
        if column_name in self.headers:
            index = self.headers[column_name]
            if index < len(row):
                return row[index].strip()
        return default

    def parse_position_item_by_headers(self, row: List[str]) -> EmNormalStockPosition:
        """基于表头解析持仓项"""
        item = EmNormalStockPosition()
        try:
            # 使用表头映射获取数据
            item.sequence = int(self.get_column_value(row, "序", "0"))
            item.stock_code = self.get_column_value(row, "证券代码")
            item.stock_name = self.get_column_value(row, "证券名称")
            item.position_quantity = self.parse_long(self.get_column_value(row, "持仓数量", "0"))
            item.available_quantity = self.parse_long(self.get_column_value(row, "可用数量", "0"))
            item.cost_price = self.parse_decimal(self.get_column_value(row, "成本价", "0"))
            item.latest_price = self.parse_decimal(self.get_column_value(row, "最新价", "0"))
            item.position_profit_loss_ratio = self.get_column_value(row, "持仓盈亏比例")
            item.position_profit_loss = self.parse_decimal(self.get_column_value(row, "持仓盈亏", "0"))
            item.daily_profit_loss_ratio = self.get_column_value(row, "当日盈亏比例")

            daily_profit_loss = self.get_column_value(row, "当日盈亏", "0")
            item.daily_profit_loss = (
                Decimal(0) if daily_profit_loss == "--"
                else self.parse_decimal(daily_profit_loss)
            )

            item.stock_position_ratio = self.get_column_value(row, "个股仓位")
            item.market_value = self.parse_decimal(self.get_column_value(row, "最新市值", "0"))

            # 可选字段，如果不存在则使用默认值
            trading_market = self.get_column_value(row, "交易市场", "")
            if hasattr(item, 'trading_market'):
                item.trading_market = trading_market

        except (IndexError, ValueError) as e:
            raise ValueError(f"解析持仓项出错(行内容: {row}): {str(e)}") from e

        return item

    def parse_position_item(self, row: List[str]) -> EmNormalStockPosition:
        """
        解析持仓项（保持向后兼容性）
        :param row: 持仓项行
        :return: 持仓项对象
        """
        item = EmNormalStockPosition()
        item.sequence = int(row[0])
        item.stock_code = row[1]
        item.stock_name = row[2]
        item.position_quantity = self.parse_long(row[3])
        item.available_quantity = self.parse_long(row[4])
        item.cost_price = self.parse_decimal(row[5])
        item.latest_price = self.parse_decimal(row[6])
        item.position_profit_loss_ratio = row[7]
        item.position_profit_loss = self.parse_decimal(row[8])
        item.daily_profit_loss_ratio = row[9]
        item.daily_profit_loss = self.parse_decimal(row[10])
        item.stock_position_ratio = row[11]
        item.market_value = self.parse_decimal(row[12])
        return item

    def parse_decimal(self, value: str) -> Decimal:
        """
        解析十进制数
        :param value: 字符串值
        :return: 十进制数对象
        """
        try:
            return Decimal(value.replace(',', '').strip())
        except Exception:
            return Decimal(0)

    def parse_long(self, value: str) -> int:
        """
        解析长整数
        :param value: 字符串值
        :return: 长整数
        """
        try:
            return int(value.replace(',', '').strip())
        except Exception:
            return 0

# 使用示例
if __name__ == "__main__":
    try:
        sample_csv = "../../test/data/report/20250607_pt.txt"
        parser = EmNormalPositionParser()
        # 解析CSV文件
        portfolio = parser.parse(sample_csv)

        # 打印解析结果
        print("解析成功！")
        print(portfolio)
        print("持仓详情:")
        for stock in portfolio.positions:
            print(f"  {stock}")

    except Exception as e:
        print(f"解析出错: {str(e)}")